package com.fishingwithme.android.ui.viewmodels

import android.util.Log
import androidx.lifecycle.viewModelScope
import com.fishingwithme.android.data.local.PreferencesManager
import com.fishingwithme.android.data.location.LocationService
import com.fishingwithme.android.data.model.BaseInfo
import com.fishingwithme.android.data.repository.FishingRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import java.io.File
import javax.inject.Inject

data class HarvestUiState(
    val isLoading: Boolean = false,
    val isSuccess: Boolean = false,
    val error: String? = null,
    val spotId: String? = null,
    val images: List<String> = emptyList(),
    val isRec: Boolean = true,
    val score: String = "ONE",
    val harvestType: String = "KONGJUN",
    val fishTypes: List<FishType> = listOf(
        FishType("JIYU", "鲫鱼", false),
        FishType("LIYU", "鲤鱼", false),
        FishType("LUOFEI", "罗非", false),
        FishType("CAOYU", "草鱼", false),
        FishType("LINGYU", "鲮鱼", false),
        FishType("LIANYONG", "鲢鳙", false),
        FishType("HONGWEI", "红尾", false),
        FishType("HUANGWEI", "黄尾", false),
        FishType("QINGYU", "青鱼", false),
        FishType("HEIYU", "黑鱼", false),
        FishType("JUNYU", "军鱼", false),
        FishType("NIANYU", "鲶鱼", false),
        FishType("YALUO", "雅罗", false),
        FishType("QIAOZUI", "翘嘴", false),
        FishType("QINGSHAO", "青梢", false),
        FishType("LUYU", "鲈鱼", false),
        FishType("GUIYU", "桂鱼", false),
        FishType("HUANGLADING", "黄辣丁", false),
        FishType("CIYANZUN", "刺眼", false),
        FishType("MAKOU", "马口", false),
        FishType("BAITIAO", "白条", false),
        FishType("LANDAO", "蓝刀", false)
    ),
    val scores: List<ScoreType> = listOf(
        ScoreType("ONE", "1分", true),
        ScoreType("TWO", "2分", false),
        ScoreType("THREE", "3分", false),
        ScoreType("FOUR", "4分", false),
        ScoreType("FIVE", "5分", false)
    ),
    val harvestTypes: List<HarvestType> = listOf(
        HarvestType("BAOHU", "爆护", false),
        HarvestType("NORMAL", "正常", false),
        HarvestType("KONGJUN", "空军", true)
    ),
    val comment: String = "",
    // Search related fields
    val searchQuery: String = "",
    val searchResults: List<com.fishingwithme.android.data.model.Spot> = emptyList(),
    val isSearching: Boolean = false,
    // Location related fields
    val isGettingLocation: Boolean = false
)

data class FishType(
    val code: String,
    val name: String,
    val checked: Boolean
)

data class ScoreType(
    val code: String,
    val name: String,
    val checked: Boolean
)

data class HarvestType(
    val code: String,
    val name: String,
    val checked: Boolean
)

@HiltViewModel
class HarvestViewModel @Inject constructor(
    private val repository: FishingRepository,
    private val preferencesManager: PreferencesManager,
    private val locationService: LocationService
) : BaseViewModel(preferencesManager) {

    private val _uiState = MutableStateFlow(HarvestUiState())
    val uiState: StateFlow<HarvestUiState> = _uiState.asStateFlow()

    fun setSpotId(spotId: String) {
        _uiState.update { it.copy(spotId = spotId) }
    }

    fun updateImages(images: List<String>) {
        _uiState.update { it.copy(images = images) }
    }

    fun toggleRec() {
        _uiState.update { it.copy(isRec = !it.isRec) }
    }

    fun setScore(score: String) {
        val updatedScores = _uiState.value.scores.map { scoreType ->
            scoreType.copy(checked = scoreType.code == score)
        }
        _uiState.update { 
            it.copy(
                score = score,
                scores = updatedScores
            ) 
        }
    }

    fun setHarvestType(type: String) {
        val updatedTypes = _uiState.value.harvestTypes.map { harvestType ->
            harvestType.copy(checked = harvestType.code == type)
        }
        _uiState.update { 
            it.copy(
                harvestType = type,
                harvestTypes = updatedTypes
            ) 
        }
    }

    fun toggleFishType(code: String) {
        val updatedFishTypes = _uiState.value.fishTypes.map { fishType ->
            if (fishType.code == code) {
                fishType.copy(checked = !fishType.checked)
            } else {
                fishType
            }
        }
        _uiState.update { it.copy(fishTypes = updatedFishTypes) }
    }

    fun setComment(comment: String) {
        _uiState.update { it.copy(comment = comment) }
    }

    suspend fun uploadImage(file: File): Flow<Result<String>> {
        return repository.uploadFile(file)
    }

    fun getLocationAndSubmit() {
        viewModelScope.launch {
            _uiState.update { it.copy(isGettingLocation = true, error = null) }
            
            try {
                // Get precise location
                val locationResult = locationService.getCurrentLocation()
                locationResult.fold(
                    onSuccess = { position ->
                        // Use the position to find nearby spots
                        repository.loadSpots(position.latitude, position.longitude).collect { spotsResult ->
                            spotsResult.fold(
                                onSuccess = { spots ->
                                    if (spots.isNotEmpty()) {
                                        // Automatically select the first spot
                                        val firstSpot = spots.first()
                                        _uiState.update { 
                                            it.copy(
                                                isGettingLocation = false,
                                                spotId = firstSpot.id,
                                                searchQuery = firstSpot.name,
                                                searchResults = spots,
                                                error = "已根据位置自动选择最近的钓点: ${firstSpot.name}"
                                            ) 
                                        }
                                    } else {
                                        _uiState.update { 
                                            it.copy(
                                                isGettingLocation = false,
                                                error = "在当前位置附近未找到钓点，请手动搜索或添加新钓点"
                                            ) 
                                        }
                                    }
                                },
                                onFailure = { exception ->
                                    _uiState.update { 
                                        it.copy(
                                            isGettingLocation = false,
                                            error = "获取附近钓点失败: ${exception.message ?: "未知错误"}"
                                        ) 
                                    }
                                }
                            )
                        }
                    },
                    onFailure = { exception ->
                        _uiState.update { 
                            it.copy(
                                isGettingLocation = false,
                                error = "获取位置失败: ${exception.message ?: "未知错误"}，请确保已开启GPS并处于户外开阔区域"
                            ) 
                        }
                    }
                )
            } catch (e: Exception) {
                _uiState.update { 
                    it.copy(
                        isGettingLocation = false,
                        error = "获取位置时发生错误: ${e.message ?: "未知错误"}"
                    ) 
                }
            }
        }
    }

    fun submitHarvest() {
        val state = _uiState.value
        val spotId = state.spotId ?: return
        
        // Validate required fields
        if (state.images.isEmpty()) {
            _uiState.update { it.copy(error = "请上传渔获图片") }
            return
        }
        
        val selectedFishTypes = state.fishTypes.filter { it.checked }.map { it -> it.code }
        if (selectedFishTypes.isEmpty()) {
            _uiState.update { it.copy(error = "请选择鱼种") }
            return
        }
        
        viewModelScope.launch {
            _uiState.update { it.copy(isLoading = true, error = null) }
            
            try {
                // Get current user object from preferences
                val user = preferencesManager.getLoginUserObj().first()
                val userId = user?.id ?: "unknown"
                
                // Get city code from preferences
                val cityLocation = preferencesManager.getCurrentCityLocation().first()
                
                // Find selected harvest type and score
                val selectedHarvestType = state.harvestTypes.find { it.checked } ?: state.harvestTypes.first()
                val selectedScore = state.scores.find { it.checked } ?: state.scores.first()

                
                // Create HarvestSubmission DTO instead of using a Map
                val harvestSubmission = com.fishingwithme.android.data.model.HarvestSubmission(
                    visitId = userId,
                    spotId = spotId,
                    pictures = state.images,
                    isRec = state.isRec,
                    harvestType = selectedHarvestType.code,
                    score = selectedScore.code,
                    comment = state.comment,
                    cityCode = cityLocation?.city?.cityCode,
                    fishes = selectedFishTypes
                )
                
                repository.addVisitHarvest(harvestSubmission).collect { response ->
                    response.fold(
                        onSuccess = {
                            _uiState.update { 
                                it.copy(
                                    isLoading = false,
                                    isSuccess = true,
                                    error = null
                                ) 
                            }
                        },
                        onFailure = { exception ->
                            val handledException = handleException(exception as Exception)
                            _uiState.update { 
                                it.copy(
                                    isLoading = false,
                                    error = handledException.message ?: "提交失败"
                                ) 
                            }
                        }
                    )
                }
            } catch (e: Exception) {
                _uiState.update { 
                    it.copy(
                        isLoading = false,
                        error = e.message ?: "提交失败"
                    ) 
                }
            }
        }
    }

    fun clearError() {
        _uiState.update { it.copy(error = null) }
    }
    
    fun setSearchQuery(query: String) {
        _uiState.update { it.copy(searchQuery = query) }
    }
    
    fun searchSpots() {
        val query = _uiState.value.searchQuery
        if (query.isEmpty()) {
            _uiState.update { it.copy(searchResults = emptyList(), isSearching = false) }
            return
        }
        
        Log.d("HarvestViewModel", "Searching for spots with query: $query")
        
        viewModelScope.launch {
            _uiState.update { it.copy(isSearching = true, error = null) }
            
            try {
                repository.searchSpots(query).collect { response ->
                    response.fold(
                        onSuccess = { spots ->
                            Log.d("HarvestViewModel", "Successfully found ${spots.size} spots")
                            spots.forEach { spot ->
                                Log.d("HarvestViewModel", "Spot: ${spot.name}, ID: ${spot.id}")
                            }
                            _uiState.update { 
                                it.copy(
                                    searchResults = spots,
                                    isSearching = false,
                                    error = null
                                ) 
                            }
                        },
                        onFailure = { exception ->
                            Log.e("HarvestViewModel", "Failed to search spots", exception)
                            val handledException = handleException(exception as Exception)
                            _uiState.update { 
                                it.copy(
                                    isSearching = false,
                                    error = handledException.message ?: "搜索失败"
                                ) 
                            }
                        }
                    )
                }
            } catch (e: Exception) {
                Log.e("HarvestViewModel", "Exception while searching spots", e)
                _uiState.update { 
                    it.copy(
                        isSearching = false,
                        error = e.message ?: "搜索失败"
                    ) 
                }
            }
        }
    }
    
    fun selectSpot(spotId: String, spotName: String) {
        Log.d("HarvestViewModel", "Selecting spot: id=$spotId, name=$spotName")
        _uiState.update { 
            it.copy(
                spotId = spotId,
                searchQuery = spotName,
                searchResults = emptyList()
            ) 
        }
    }

}